home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / More Source / Libraries / SpriteEngine / SE Balls / SpriteHanders.c < prev    next >
C/C++ Source or Header  |  1995-03-11  |  4KB  |  149 lines

  1. #include "SpriteTools.h"
  2.  
  3. // SpriteTools.h includes SpriteHandlers.h
  4.  
  5.  
  6. /*** Custom handlers - application dependent ***
  7.  
  8. Edit this as necessary. It should always include the following three routines:
  9.  
  10. MoveSprite: move the sprite
  11.  
  12. HitSprite: handle collisions between two sprites
  13.  
  14. InitSprites: Load all faces and create initial sprites
  15.  
  16. ***/
  17.  
  18.  
  19. GrafPtr    firstFace, secondFace, thirdFace;
  20.  
  21.  
  22. /* SeparateBalls is explicitly written to separate two balls with
  23. diameter 32. */
  24.  
  25. #define kBallDiameterSquared (33*33)
  26.  
  27. static void SeparateBalls(SpritePtr theSprite, SpritePtr anotherSprite)
  28. {
  29.     Point initVector, nowVector;
  30.     short absH, absV;
  31.     short moveH, moveV;
  32.     short frac;
  33.  
  34. /*Separate*/
  35.     frac = 0;
  36.     initVector.h = theSprite->position.h - anotherSprite->position.h;
  37.     initVector.v = theSprite->position.v - anotherSprite->position.v;
  38.     absH = abs(initVector.h);
  39.     absV = abs(initVector.v);
  40.     moveH = Sgn(initVector.h);
  41.     moveV = Sgn(initVector.v);
  42.     if ( moveH == 0 )
  43.         if ( moveV == 0 )
  44.             moveV = 1;
  45.     do
  46.     {
  47.         if ( absH > absV )
  48.         {
  49.             theSprite->position.h = theSprite->position.h + moveH;
  50.             anotherSprite->position.h = anotherSprite->position.h - moveH;
  51.             frac = frac + absV;
  52.             if ( frac > absH )
  53.             {
  54.                 theSprite->position.v = theSprite->position.v + moveV;
  55.                 anotherSprite->position.v = anotherSprite->position.v - moveV;
  56.                 frac = frac - absH;
  57.             }
  58.         }
  59.         else
  60.         {
  61.             theSprite->position.v = theSprite->position.v + moveV;
  62.             anotherSprite->position.v = anotherSprite->position.v - moveV;
  63.             frac = frac + absH;
  64.             if ( frac > absV )
  65.             {
  66.                 theSprite->position.h = theSprite->position.h + moveH;
  67.                 anotherSprite->position.h = anotherSprite->position.h - moveH;
  68.                 frac = frac - absV;
  69.             }
  70.         }
  71.  
  72.         nowVector.h = theSprite->position.h - anotherSprite->position.h;
  73.         nowVector.v = theSprite->position.v - anotherSprite->position.v;
  74.     } while (!  (long)nowVector.h * nowVector.h + (long)nowVector.v * nowVector.v > kBallDiameterSquared);
  75. } /*SeparateBalls*/
  76.  
  77.  
  78.  
  79. void MoveSprite(SpritePtr theSprite)
  80. {
  81.  
  82.     theSprite->speed.v++; // Simple gravity
  83.     theSprite->fixedPointPosition.h += theSprite->speed.h;
  84.     theSprite->fixedPointPosition.v += theSprite->speed.v;
  85.     theSprite->position.h = theSprite->fixedPointPosition.h >> 4;
  86.     theSprite->position.v = theSprite->fixedPointPosition.v >> 4;
  87.     KeepOnScreenFixed(theSprite);
  88.  
  89. } /*MoveSprite*/
  90.  
  91.  
  92. void HitSprite(SpritePtr theSprite, SpritePtr anotherSprite)
  93. {
  94.     Point    perpendicularHelpLine, parallelHelpLine, p1, p2, n1, n2;
  95.  
  96. //Check for a *real* collision!
  97.     if (RegionHit(theSprite, anotherSprite))
  98.     {
  99.         perpendicularHelpLine.h = theSprite->position.h - anotherSprite->position.h;
  100.         perpendicularHelpLine.v = theSprite->position.v - anotherSprite->position.v;
  101.         parallelHelpLine.h = perpendicularHelpLine.v;
  102.         parallelHelpLine.v = -perpendicularHelpLine.h;
  103. //Move them away from each other}
  104.         SeparateBalls(theSprite, anotherSprite);
  105. //Make the fixed-point positions follow!
  106.         theSprite->fixedPointPosition.h = theSprite->position.h << 4;
  107.         theSprite->fixedPointPosition.v = theSprite->position.v << 4;
  108.         anotherSprite->fixedPointPosition.h = anotherSprite->position.h << 4;
  109.         anotherSprite->fixedPointPosition.v = anotherSprite->position.v << 4;
  110.  
  111. //Swap the speed components that are parallell to parallelHelpLine
  112.         SplitVector(theSprite->speed, parallelHelpLine, &p1, &n1);
  113.         SplitVector(anotherSprite->speed, parallelHelpLine, &p2, &n2);
  114.  
  115.         anotherSprite->speed.h = p2.h + n1.h;
  116.         anotherSprite->speed.v = p2.v + n1.v;
  117.  
  118.         theSprite->speed.h = p1.h + n2.h;
  119.         theSprite->speed.v = p1.v + n2.v;
  120.     } // if RegionHit
  121. } /*HitSprite*/
  122.  
  123.  
  124. void InitSprites()
  125. {
  126.     SpritePtr    theSprite;
  127.  
  128. /*Load all pictures*/
  129.     firstFace = LoadFaceFromCicn(128);            /*cicn resource #128.*/
  130.     secondFace = LoadFaceFromCicn(129);            /*cicn resource #129.*/
  131.     thirdFace = LoadFaceFromCicn(130);            /*cicn resource #130.*/
  132.  
  133. /*Create sprites*/
  134.     theSprite = NewSprite();
  135.     theSprite->face = firstFace;
  136.     SetPt(&theSprite->fixedPointPosition, 100 << 4, 100 << 4);
  137.     SetPt(&theSprite->speed, 1, 16);
  138.  
  139.     theSprite = NewSprite();
  140.     theSprite->face = secondFace;
  141.     SetPt(&theSprite->fixedPointPosition, 50 << 4, 50 << 4);
  142.     SetPt(&theSprite->speed, 16, 1);
  143.  
  144.     theSprite = NewSprite();
  145.     theSprite->face = thirdFace;
  146.     SetPt(&theSprite->fixedPointPosition, 150 << 4, 150 << 4);
  147.     SetPt(&theSprite->speed, Rand(7)-3, Rand(7)-3);
  148. } /*InitSprites*/
  149.